package edu.nus.iss.t5.jass.dao;

import java.io.IOException;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;


import edu.nus.iss.t5.jass.entity.JobAdvertisement;
import edu.nus.iss.t5.jass.entity.Entity;
import edu.nus.iss.t5.jass.exception.DAOException;
import edu.nus.iss.t5.jass.exception.DuplicateEntityException;
import edu.nus.iss.t5.jass.util.DateUtil;


/**
 * 
 * AdvertisementDAO extends from IGenericDAO which implements retrieve, add, remove and modify advertisements from
 * advertisement.properties file.
 * 
 * @see IGenericDAO
 * @author Modified by Abdul Khader Azeem
 */
public class JobAdvertDAO extends IGenericDAO {
	public static int STATUS_DELETED = -1;
	private static String advertDaoFile="data\\advertisement.properties";
	private static String baseKey = "baseKey";  
	private final String company= "companyDesc";
	private final String owner= "owner";
	private final String jobDescription= "jobDescription";
	private final String technicalSkills="technicalSkills";
	private final String managementSkills="managementSkills";
	private final String status="status";
	private final String postingDate="postingDate";
	private final String expiryDate="expiryDate";
	private final String requiredStartDate="requiredStartDate";
	private final String salaryMin="salaryMin";
	private final String salaryMax="salaryMax";
	private final String requiredWorkingExperience="requiredWorkingExperience";
	private final String location="location";
	private final String title="title";
	private final String creationDate="creationDate";
	private final String modifyDate="modifyDate";
	
	
	public JobAdvertDAO() throws IOException {
		super(advertDaoFile, baseKey);
	}
	
	public void update(Entity e) throws IOException {
		JobAdvertisement ad = new JobAdvertisement((JobAdvertisement)e);
		//if(getObject().get(e.getId()) != null)
		getObject().put(e.getId(), ad);
		int key = Integer.parseInt(e.getId());
		Properties props= getProperties();
		props.setProperty(baseKey+key, ad.getId());
		props.setProperty(company+key, ad.getCompany());
		props.setProperty(owner+key, ad.getOwner());
		props.setProperty(jobDescription+key, ad.getJobDescription());
		props.setProperty(technicalSkills+key, ad.getTechnicalSkills());
		props.setProperty(managementSkills+key, ad.getManagementSkills());
		props.setProperty(status+key, ad.getStatus()+"");
		
		props.setProperty(postingDate+key, DateUtil.convertDateToStr(ad.getPostingDate()));  
		props.setProperty(expiryDate+key, DateUtil.convertDateToStr(ad.getExpiryDate()));
		props.setProperty(requiredStartDate+key, DateUtil.convertDateToStr(ad.getRequiredStartDate()));
		
		props.setProperty(salaryMin+key, ad.getSalaryMin()+"");
		props.setProperty(salaryMax+key, ad.getSalaryMax()+"");
		props.setProperty(requiredWorkingExperience+key, ad.getRequiredWorkingExperience()+"");		
		props.setProperty(location+key, ad.getLocation());
		props.setProperty(title+key, ad.getTitle());
		props.setProperty(creationDate+key, DateUtil.convertDateToStr(ad.getCreationDate()));
		props.setProperty(modifyDate+key, DateUtil.convertDateToStr(ad.getModifyDate()));
		
		super.store();
	}
	  
	
	@Override
	//public void remove(String id) throws DAOException, IOException {
	public void remove(Entity e) throws IOException {
		JobAdvertisement ad = new JobAdvertisement((JobAdvertisement)e);
		//if(getObject().get(e.getId()) != null)
		getObject().put(e.getId(), ad);
		ad.setStatus(STATUS_DELETED);
		
		int key = Integer.parseInt(e.getId());
		Properties props= getProperties();		
		props.setProperty(baseKey+key, ad.getId());
		props.setProperty(status+key, ad.getStatus()+"");
		
		super.store();
		
		//delete from object
		/*getObject().remove(id);
		
		int int_key = getKeyForId(id);
		Properties props = getProperties();
		status =  String.valueOf(STATUS_DELETED) ;
		props.remove(baseKey+int_key);
		props.remove(company+int_key);
		props.remove(owner+int_key);
		props.remove(jobDescription+int_key);
		props.remove(technicalSkills+int_key);
		props.remove(managementSkills+int_key);
		props.remove(status+int_key);
		props.remove(postingDate+int_key);
		props.remove(expiryDate+int_key);
		props.remove(requiredStartDate+int_key);
		props.remove(salaryMin+int_key);
		props.remove(salaryMax+int_key);
		props.remove(requiredWorkingExperience+int_key);		
		props.remove(location+int_key);
		props.remove(title+int_key);
		props.remove(creationDate+int_key);
		props.remove(modifyDate+int_key);*/
		
		//persist the changes
		//store();
	}
	
	public Entity get(String id) throws ParseException {
		JobAdvertisement advertDto = null;
		
		advertDto = (JobAdvertisement) getObject().get(id);
		if( advertDto == null )
		{	
			Properties props = getProperties();
			int dStatus = 0;
			if(id.startsWith(status)){
				dStatus = Integer.parseInt(props.getProperty(id));
			}
			System.out.println("dStatus "+dStatus);
			if(dStatus!=-1){
			int int_key = getKeyForId(id);
			if(int_key == -1)
				return null;
							
			advertDto = new JobAdvertisement();
			advertDto.setKey(int_key);
			advertDto.setId(String.valueOf(int_key));
			advertDto.setBaseCode(props.getProperty(baseKey+int_key));
						
			advertDto.setCompany(props.getProperty(company+int_key));
						
			advertDto.setOwner(props.getProperty(owner+int_key));
						
			advertDto.setJobDescription(props.getProperty(jobDescription+int_key));
						
			advertDto.setTechnicalSkills(props.getProperty(technicalSkills+int_key));
			
			advertDto.setManagementSkills(props.getProperty(managementSkills+int_key));			
			
			advertDto.setStatus(Integer.parseInt(props.getProperty(status+int_key)));
	
			advertDto.setPostingDate(DateUtil.convertStrToDate(props.getProperty(postingDate+int_key)));
						
			advertDto.setExpiryDate(DateUtil.convertStrToDate(props.getProperty(expiryDate+int_key)));
									
			advertDto.setRequiredStartDate(DateUtil.convertStrToDate(props.getProperty(requiredStartDate+int_key)));
						
			advertDto.setSalaryMin(Integer.parseInt(props.getProperty(salaryMin+int_key)));
						
			advertDto.setSalaryMax(Integer.parseInt(props.getProperty(salaryMax+int_key)));
			
			advertDto.setRequiredWorkingExperience(Integer.parseInt(props.getProperty(requiredWorkingExperience+int_key)));			
			
			advertDto.setLocation(props.getProperty(location+int_key));
						
			advertDto.setTitle(props.getProperty(title+int_key));
			
			advertDto.setCreationDate(DateUtil.convertStrToDate(props.getProperty(creationDate+int_key)));
			
			advertDto.setModifyDate(DateUtil.convertStrToDate(props.getProperty(modifyDate+int_key)));
			
			//add  to object
			getObject().put(id, advertDto);        
		}
		}
		return new JobAdvertisement(advertDto);   
	  }
	  
	 
	  @Override
	  public void save(Entity e) throws DAOException, IOException, DuplicateEntityException {
		     
		  int new_index = getNextMaxEntityIndex();
		  e.setKey(new_index);
		  e.setId(new_index+"");
		  JobAdvertisement ad = new JobAdvertisement((JobAdvertisement)e);	  
		  getObject().put(e.getId(), ad);
		  Properties props = getProperties();
		  System.out.println("ad.getId() in add "+ad.getId());
		  props.put(baseKey+new_index, ad.getId());
		  //props.put(company+new_index, ad.getCompany());
		  props.put(owner+new_index, ad.getOwner());
		  props.put(jobDescription+new_index, ad.getJobDescription());
		  props.put(technicalSkills+new_index, ad.getTechnicalSkills());
		  props.put(managementSkills+new_index, ad.getManagementSkills());
		  props.put(status+new_index, ad.getStatus()+"");
		  
		  props.put(postingDate+new_index, DateUtil.convertDateToStr(ad.getPostingDate()));  //use format to convert to one particular format
		  props.put(expiryDate+new_index, DateUtil.convertDateToStr(ad.getExpiryDate()));
		  props.put(requiredStartDate+new_index, DateUtil.convertDateToStr(ad.getRequiredStartDate()));		
		  props.put(salaryMin+new_index, ad.getSalaryMax()+"");
		  props.put(salaryMax+new_index, ad.getSalaryMin()+"");
		  props.put(requiredWorkingExperience+new_index, ad.getRequiredWorkingExperience()+"");
		  //props.put(location+new_index, ad.getLocation());
		  props.put(title+new_index, ad.getTitle());
		  props.put(creationDate+new_index, DateUtil.convertDateToStr(ad.getCreationDate()));
		  props.put(modifyDate+new_index, DateUtil.convertDateToStr(ad.getModifyDate()));
		   
		  
		  //persist the new object
		  store();
	  }

	  
		  public  Entity[] getAll() {
			  HashMap<String,Entity> map = new HashMap<String, Entity>();
			  	Properties props = getProperties();
				Set<Object> keys = props.keySet();
				Iterator itr = keys.iterator();
				
				String id;
				String keyID="";
				while(itr.hasNext()) { 
					id = (String)itr.next();
					boolean flag = false;
					
					JobAdvertisement dto = new JobAdvertisement();
					if(id.startsWith(baseKey))
					{
						keyID = id.substring(baseKey.length());
						if(map.containsKey(keyID))
						{
						  	((JobAdvertisement)map.get(keyID)).setId(props.getProperty(id));
						}
						else
						{							
							dto.setId(props.getProperty(id));					
							flag = true;
						}
					}
					else if(id.startsWith(company))
					{
						keyID = id.substring(company.length());
						if(map.containsKey(keyID))
						{
						  	((JobAdvertisement)map.get(keyID)).setCompany(props.getProperty(id));
						}
						else
						{							
							dto.setCompany(props.getProperty(id));
							flag = true;
						}
					}
					else if(id.startsWith(owner))
					{
						keyID = id.substring(owner.length());
						if(map.containsKey(keyID))
						{
						  	((JobAdvertisement)map.get(keyID)).setOwner(props.getProperty(id));
						}
						else
						{
							dto.setOwner(props.getProperty(id));
							flag = true;
						}
					}
					else if(id.startsWith(jobDescription))
					{
						keyID = id.substring(jobDescription.length());
						if(map.containsKey(keyID))
						{
						  	((JobAdvertisement)map.get(keyID)).setJobDescription(props.getProperty(id));
						}
						else
						{
							
							dto.setJobDescription(props.getProperty(id));
							flag = true;
						}
					}
					else if(id.startsWith(technicalSkills))
					{
						keyID = id.substring(technicalSkills.length());
						if(map.containsKey(keyID))
						{
						  	((JobAdvertisement)map.get(keyID)).setTechnicalSkills(props.getProperty(id));
						}
						else
						{							
							dto.setTechnicalSkills(props.getProperty(id));
							flag = true;
						}
					}
					else if(id.startsWith(managementSkills))
					{
						keyID = id.substring(managementSkills.length());
						if(map.containsKey(keyID))
						{
						  	((JobAdvertisement)map.get(keyID)).setManagementSkills(props.getProperty(id));
						}
						else
						{
							
							dto.setManagementSkills(props.getProperty(id));
							flag = true;
						}
					}
					else if(id.startsWith(status))
					{
						keyID = id.substring(status.length());
						if(map.containsKey(keyID))
						{
						  	((JobAdvertisement)map.get(keyID)).setStatus(Integer.parseInt(props.getProperty(id)));
						}
						else
						{
							
							dto.setStatus(Integer.parseInt(props.getProperty(id)));
							flag = true;
						}
					}
					else if(id.startsWith(postingDate))
					{
						keyID = id.substring(postingDate.length());
						if(map.containsKey(keyID))
						{
						  	try {
								((JobAdvertisement)map.get(keyID)).setPostingDate(DateUtil.convertStrToDate(props.getProperty(id)));
							} catch (ParseException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						}
						else
						{
							
							try {
								dto.setPostingDate(DateUtil.convertStrToDate(props.getProperty(id)));
							} catch (ParseException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
							flag = true;
						}
					}		
					else if(id.startsWith(expiryDate))
					{
						keyID = id.substring(expiryDate.length());
						if(map.containsKey(keyID))
						{
						  	try {
								((JobAdvertisement)map.get(keyID)).setExpiryDate(DateUtil.convertStrToDate(props.getProperty(id)));
							} catch (ParseException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						}
						else
						{
							
							try {
								dto.setExpiryDate(DateUtil.convertStrToDate(props.getProperty(id)));
							} catch (ParseException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
							flag = true;
						}
					}			
					else if(id.startsWith(requiredStartDate))
					{
						keyID = id.substring(requiredStartDate.length());
						if(map.containsKey(keyID))
						{
						  	try {
								((JobAdvertisement)map.get(keyID)).setRequiredStartDate(DateUtil.convertStrToDate(props.getProperty(id)));
							} catch (ParseException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						}
						else
						{
							
							try {
								dto.setRequiredStartDate(DateUtil.convertStrToDate(props.getProperty(id)));
							} catch (ParseException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
							flag = true;
						}
					}			
					else if(id.startsWith(salaryMin))
					{
						keyID = id.substring(salaryMin.length());
						if(map.containsKey(keyID))
						{
						  	((JobAdvertisement)map.get(keyID)).setSalaryMin(Integer.parseInt(props.getProperty(id)));
						}
						else
						{
							
							dto.setSalaryMin(Integer.parseInt(props.getProperty(id)));
							flag = true;
						}
					}			
					else if(id.startsWith(salaryMax))
					{
						keyID = id.substring(salaryMax.length());
						if(map.containsKey(keyID))
						{
						  	((JobAdvertisement)map.get(keyID)).setSalaryMax(Integer.parseInt(props.getProperty(id)));
						}
						else
						{
							
							dto.setSalaryMax(Integer.parseInt(props.getProperty(id)));
							flag = true;
						}
					}
					else if(id.startsWith(requiredWorkingExperience))
					{
						keyID = id.substring(requiredWorkingExperience.length());
						if(map.containsKey(keyID))
						{
						  	((JobAdvertisement)map.get(keyID)).setRequiredWorkingExperience(Integer.parseInt(props.getProperty(id)));
						}
						else
						{
							
							dto.setRequiredWorkingExperience(Integer.parseInt(props.getProperty(id)));
							
						}
					}
					else if(id.startsWith(title))
					{
						keyID = id.substring(title.length());
						if(map.containsKey(keyID))
						{
						  	((JobAdvertisement)map.get(keyID)).setTitle(props.getProperty(id));
						}
						else
						{
							
							dto.setTitle(props.getProperty(id));
							flag = true;
						}
					}		
					else if(id.startsWith(location))
					{
						keyID = id.substring(location.length());
						if(map.containsKey(keyID))
						{
						  	((JobAdvertisement)map.get(keyID)).setLocation(props.getProperty(id));
						}
						else
						{
							
							dto.setLocation(props.getProperty(id));
							flag = true;
							
						}
					}
					else if(id.startsWith(creationDate))
					{
						keyID = id.substring(creationDate.length());
						if(map.containsKey(keyID))
						{
						  	try {
								((JobAdvertisement)map.get(keyID)).setCreationDate(DateUtil.convertStrToDate(props.getProperty(id)));
							} catch (ParseException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						}
						else
						{
							
							try {
								dto.setCreationDate(DateUtil.convertStrToDate(props.getProperty(id)));
							} catch (ParseException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
							flag = true;
							
						}
					}
					else if(id.startsWith(modifyDate))
					{
						keyID = id.substring(modifyDate.length());
						if(map.containsKey(keyID))
						{
						  	try {
								((JobAdvertisement)map.get(keyID)).setModifyDate(DateUtil.convertStrToDate(props.getProperty(id)));
							} catch (ParseException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						}
						else
						{
							
							try {
								dto.setModifyDate(DateUtil.convertStrToDate(props.getProperty(id)));
							} catch (ParseException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
							flag = true;
							
						}
					}
					
					if(flag){
					int int_key = Integer.parseInt(keyID);
					dto.setKey(int_key);					
					map.put(keyID, dto);					
					}
				} 
				
				Entity[] entity= new Entity[map.size()];
				int i=0;
				Iterator itrJobseeker = map.values().iterator();
				while(itrJobseeker.hasNext()) { 
					entity[i]= (Entity)itrJobseeker.next();
					i++;
				}
				
				return entity;
		  }
	
		  }
